<template>
  <div class="add-contribution">
    <div class="header">
      <h2>新增投稿</h2>
    </div>
    <div class="content">
      <a-form-model ref="form" :model="form" :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
        <a-form-model-item label="作品名" prop="title">
          <a-input v-model="form.title" placeholder="请输入作品名" />
        </a-form-model-item>

        <a-form-model-item label="作者1" prop="author1">
          <!-- <a-select v-model="form.author1" placeholder="请选择作者1" :loading="personLoading" show-search
            :filter-option="false" :default-active-first-option="false" :show-arrow="false"
            :not-found-content="personLoading ? '加载中...' : '未找到'" @search="handleSearchPerson1">
            <a-select-option v-for="item in personList1" :key="item.person_id" :value="item.person_id">
              {{ item.person_name }} ({{ item.department_name }})
            </a-select-option>
          </a-select> -->

          <a-tree-select v-model="form.author1" show-search style="width: 100%" treeNodeFilterProp="title"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :tree-data="personListTree1"
            placeholder="请选择作者1">
          </a-tree-select>
        </a-form-model-item>

        <a-form-model-item label="作者2" prop="author2">
          <!-- <a-select v-model="form.author2" placeholder="请选择作者2（选填）" :loading="personLoading" show-search
            :filter-option="false" :default-active-first-option="false" :show-arrow="false"
            :not-found-content="personLoading ? '加载中...' : '未找到'" @search="handleSearchPerson2" allowClear>
            <a-select-option v-for="item in personList2" :key="item.person_id" :value="item.person_id">
              {{ item.person_name }} ({{ item.department_name }})
            </a-select-option>
          </a-select> -->

          <a-tree-select v-model="form.author2" show-search style="width: 100%" treeNodeFilterProp="title"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :tree-data="personListTree2"
            placeholder="请选择作者2">
          </a-tree-select>
        </a-form-model-item>

        <a-form-model-item label="作者3" prop="author3">
          <!-- <a-select v-model="form.author3" placeholder="请选择作者3（选填）" :loading="personLoading" show-search
            :filter-option="false" :default-active-first-option="false" :show-arrow="false"
            :not-found-content="personLoading ? '加载中...' : '未找到'" @search="handleSearchPerson3" allowClear>
            <a-select-option v-for="item in personList3" :key="item.person_id" :value="item.person_id">
              {{ item.person_name }} ({{ item.department_name }})
            </a-select-option>
          </a-select> -->

          <a-tree-select v-model="form.author3" show-search style="width: 100%" treeNodeFilterProp="title"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :tree-data="personListTree3"
            placeholder="请选择作者3">
          </a-tree-select>
        </a-form-model-item>

        <a-form-model-item label="项目组" prop="project_group_id">
          <a-select v-model="form.project_group_id" placeholder="请选择项目组（选填）" :loading="projectGroupLoading" show-search
            :filter-option="false" :default-active-first-option="false" :show-arrow="false"
            :not-found-content="projectGroupLoading ? '加载中...' : '未找到'" @search="handleSearchProjectGroup" allowClear>
            <a-select-option v-for="item in projectGroupList" :key="item.project_group_id"
              :value="item.project_group_id">
              {{ item.project_group_name }}
            </a-select-option>
          </a-select>
        </a-form-model-item>

        <!-- 选择文件 -->
        <a-form-item label="选择文件" prop="file" required>
          <a-upload accept="audio/mp4, video/mp4" :file-list="uploadFileList" :before-upload="handleBeforeUpload"
            :remove="handleRemoveFile">
            <a-button>
              <a-icon type="upload" /> 上传文件 </a-button>
            <br>
            <span style="color:rgb(157 157 157);font-size:12px;">支持扩展名.mp4,文件大小限制为1GB</span>
          </a-upload>
          <a-progress :percent="uploadPercent" :status="uploadStatus" />
        </a-form-item>



        <a-form-model-item label="备注" prop="remarks">
          <a-textarea v-model="form.remarks" placeholder="请输入备注信息" :rows="4" />
        </a-form-model-item>

        <a-form-model-item :wrapper-col="{ span: 16, offset: 4 }">
          <a-button type="primary" :loading="submitting" @click="handleSubmit">
            提交
          </a-button>
          <a-button style="margin-left: 10px" @click="handleReset">
            重置
          </a-button>
        </a-form-model-item>
      </a-form-model>
    </div>
  </div>
</template>

<script>
  import moment from 'moment'

  import {
    apiContributionCreate,
    apiPersonGetAllList,
    apiPersonGetAllListTree,
    apiProjectGroupList
  } from '@/api/featch'

  const client = new AWS.S3({
    accessKeyId: 'B0EBM7IA33R7RE9M8BPY',
    secretAccessKey: 'ABb5DiBletAUO1AmcMT6M1wORLtBUh0OZXWZ6zn5',
    endpoint: 'https://hangzhou7.zos.ctyun.cn',
    sslEnabled: true,
    s3ForcePathStyle: true,
  })

  const Bucket = 'jyrmggcc'

  const personInfo = JSON.parse(window.sessionStorage.getItem('person_info') || '{}')


  export default {
    name: 'AddContribution',
    data() {
      return {
        personInfo,
        // 表单数据
        form: {
          title: '',
          author1: undefined,
          author2: undefined,
          author3: undefined,
          project_group_id: undefined,
          video_file_path: null,
          remarks: ''
        },

        // 表单验证规则
        rules: {
          title: [{
              required: true,
              message: '请输入作品名',
              trigger: 'blur'
            },
            {
              min: 2,
              max: 100,
              message: '长度在 2 到 100 个字符',
              trigger: 'blur'
            }
          ],
          author1: [{
            required: true,
            message: '请选择作者1',
            trigger: 'change'
          }],
        },

        uploadFileList: [],
        binaryString: null,
        UploadId: null,
        PartNumber: 1,
        totalPart: 0,
        Parts: [],
        uploadStatus: 'active',

        // 人员列表
        personList1: [], // 作者1列表
        personList2: [], // 作者2列表
        personList3: [], // 作者3列表
        personListTree1: [],
        personListTree2: [],
        personListTree3: [],
        personLoading: false,

        // 项目组列表
        projectGroupList: [],
        projectGroupLoading: false,

        // 提交状态
        submitting: false
      }
    },
    mounted() {
      // this.getInitialPersonList()
      this.getInitialPersonListTree()
      this.handleSearchProjectGroup()
    },
    computed: {
      uploadPercent() {
        if (this.PartNumber === 0 || this.totalPart === 0) {
          return 0
        } else {
          return Math.ceil((this.PartNumber / this.totalPart) * 100)
        }
      }
    },
    methods: {
      /**
       * @description 获取初始人员列表
       */
      async getInitialPersonList() {
        this.personLoading = true
        try {
          const res = await apiPersonGetAllList({})
          if (res.code === 200) {
            this.personList1 = [...res.data]
            this.personList2 = [...res.data]
            this.personList3 = [...res.data]
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.personLoading = false
      },
      /**
       * @description 获取初始人员列表 树状
       */
      async getInitialPersonListTree() {
        this.personLoading = true
        try {
          const res = await apiPersonGetAllListTree({})
          if (res.code === 200) {
            console.log(res.data)
            this.personListTree1 = [...res.data]
            this.personListTree2 = [...res.data]
            this.personListTree3 = [...res.data]
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.personLoading = false
      },
      /**
       * @description 搜索作者1
       */
      async handleSearchPerson1(value) {
        this.personLoading = true
        try {
          const res = await apiPersonGetAllList({
            person_name: value || undefined
          })
          if (res.code === 200) {
            this.personList1 = res.data
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.personLoading = false
      },

      /**
       * @description 搜索作者2
       */
      async handleSearchPerson2(value) {
        this.personLoading = true
        try {
          const res = await apiPersonGetAllList({
            person_name: value || undefined
          })
          if (res.code === 200) {
            this.personList2 = res.data
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.personLoading = false
      },

      /**
       * @description 搜索作者3
       */
      async handleSearchPerson3(value) {
        this.personLoading = true
        try {
          const res = await apiPersonGetAllList({
            person_name: value || undefined
          })
          if (res.code === 200) {
            this.personList3 = res.data
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.personLoading = false
      },

      /**
       * @description 搜索项目组
       */
      async handleSearchProjectGroup(value) {
        this.projectGroupLoading = true
        try {
          const res = await apiProjectGroupList({
            project_group_name: value || undefined
          })
          if (res.code === 200) {
            this.projectGroupList = res.data
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.projectGroupLoading = false
      },
      /**
       * @description 上传文件前
       */
      handleBeforeUpload(file, fileList) {
        console.log(file.size)
        if(file.size > (1024 * 1024 * 1024)) {
          this.$message.error('文件大小限制为1GB')
          return false
        }

        this.uploadFileList = [file]
        // 数据重置
        this.binaryString = null
        this.UploadId = null
        this.PartNumber = 1
        this.totalPart = 0
        this.Parts = []
        this.uploadStatus = 'active'
        // 文件大小
        const totalSize = file.size
        // 分块大小
        const chunkFileLength = (10 * 1024 * 1024) // 10MB
        // 分块块数
        const totalPart = Math.ceil(totalSize / chunkFileLength)
        this.totalPart = totalPart

        // 1.createMultipartUpload 初始化分片上传，传Bucket和Key,返回UploadId
        const Key = `${moment(new Date()).format('YYYY-MM-DD_HH-mm-ss')}User${personInfo.person_id}.mp4`

        let createMultipartUploadParams = {
          Bucket,
          Key
        }

        console.log('创建分片 参数:', createMultipartUploadParams)
        client.createMultipartUpload(createMultipartUploadParams, (err, data) => {
          if (err) {
            console.log('创建分片 失败:', err)
          } else {
            console.log('创建分片 成功:', data)
            this.UploadId = data.UploadId
            // 2.uploadPart 分块上传
            const uploadPartPromiseArr = []
            for (let PartNumber = 1; PartNumber <= totalPart; PartNumber++) {
              const uploadPartPromise = new Promise((resolve, reject) => {
                let uploadPartParams = {
                  Bucket: Bucket,
                  Key: Key,
                  Body: file.slice((PartNumber - 1) * chunkFileLength, (PartNumber) *
                    chunkFileLength),
                  PartNumber,
                  UploadId: this.UploadId
                }
                console.log('分块上传 编号', PartNumber)
                console.log('分块上传 参数', uploadPartParams)
                client.uploadPart(uploadPartParams, (err, data) => {
                  console.log('uploadPart', data)
                  if (err) {
                    console.log('分块上传 编号', PartNumber)
                    console.log('分块上传 失败:', err)
                    resolve({
                      PartNumber: PartNumber,
                      ETag: null,
                      err: err
                    })
                  } else {
                    console.log('分块上传 编号', PartNumber)
                    console.log('分块上传 成功:', data)
                      ++this.PartNumber
                    this.Parts.push({
                      PartNumber: PartNumber,
                      ETag: data.ETag,
                    })
                    resolve({
                      PartNumber: PartNumber,
                      ETag: data.ETag,
                    })
                  }
                })
              })
              uploadPartPromiseArr.push(uploadPartPromise)
            }

            // 各分块上传结束，完成整个分块上传
            Promise.all(uploadPartPromiseArr)
              .then(dataArr => {
                // dataArr.map(dataItem => {
                //   console.log(dataItem)
                // })
                // console.log(dataArr)
                let completeMultipartUploadParams = {
                  Bucket,
                  Key,
                  UploadId: this.UploadId,
                  MultipartUpload: {
                    Parts: this.Parts
                  }
                }
                console.log('完成整个分块上传 参数:', completeMultipartUploadParams)
                client.completeMultipartUpload(completeMultipartUploadParams, (err, data) => {
                  if (err) {
                    console.log('完成整个分块上传 失败:', err)
                    this.uploadStatus = 'exception'
                    this.$notification.error({
                      message: '上传失败',
                      description: err.stack
                    })
                  } else {
                    console.log('完成整个分块上传 成功:', data)
                    this.uploadStatus = 'success'
                    this.$notification.success({
                      message: '上传成功',
                      description: '上传成功'
                    })
                    this.form.video_file_path = data.Key

                    client.putObjectAcl({
                      Bucket,
                      Key: data.Key,
                      ACL: 'public-read'
                    }, (err, data) => {
                      if (err) console.log(err, err.stack); // an error occurred
                      else console.log(data);
                    })
                  }
                })
              })
          }
        })

        return false
      },
      /**
       * @description 移除文件
       * @callback
       */
      handleRemoveFile(file) {
        this.uploadFileList = []
        return true
      },
      /**
       * @description 提交表单
       */
      async handleSubmit() {
        if (!this.form.video_file_path) {
          this.$message.error('请上传作品')
          return
        }
        this.$refs.form.validate(async valid => {
          if (valid && this.uploadFileList[0] && this.form.video_file_path) {
            this.submitting = true
            try {
              const res = await apiContributionCreate(this.form)
              if (res.code === 200) {
                this.$message.success('投稿成功')
                this.$confirm({
                  title: '提示',
                  content: '投稿提交成功，是否返回列表页？',
                  okText: '返回列表',
                  cancelText: '继续添加',
                  onOk: () => {
                    this.$router.push('/main/contribution-list')
                  },
                  onCancel: () => {
                    this.handleReset()
                  }
                })
              } else {
                this.$message.error(res.message)
              }
            } catch (err) {
              this.$message.error(err.toString())
            }
            this.submitting = false
          }
        })
      },

      /**
       * @description 重置表单
       */
      handleReset() {
        this.$refs.form.resetFields()
        this.uploadFileList = []
        this.binaryString = null
        this.UploadId = null
        this.PartNumber = 1
        this.totalPart = 0
        this.Parts = []
        this.uploadStatus = 'active'
        // 重新获取完整的人员列表
        // this.getInitialPersonList()
        this.getInitialPersonListTree()
      }
    }
  }
</script>

<style lang="less" scoped>
  .add-contribution {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 24px;

    .header {
      margin-bottom: 12px;
      text-align: center;

      h2 {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
      }
    }

    .content {
      width: 100%;
      max-width: 800px;
      background: #fff;
      padding: 24px;
      border-radius: 4px;
      // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
    }
  }
</style>